# 若数字n为2的k次幂，我们可以通过对1进行左移k位的操作来得到。
k = 10
n = 1 << k
print(f"n = {n}, n是2的{k}次幂")
print(f"n的二进制表示是{bin(n)}")

#若想得到一个二进制数字只包含k个1的数字，我们可以通过对1进行左移k位再减1的操作来得到
k = 10
n = (1 << k) - 1
print(f"n = {n}, n是2的{k}次幂-1")
print(f"n的二进制表示是{bin(n)}，其中包含{k}个1")

"""
若数字n为2的k次幂，那么其二进制的首位一定是1，后面包含了k个0。
如16 = 0b10000，其二进制的首位为1，后面包含了4个0。
如果考虑n-1的二进制，容易发现其位数应该比n少1，同时均为1构成。
如15 = 0b1111，其二进制为4个1
由于只有当n是2的幂，才会具备上述性质，我们可以使用与运算来判断n是否为2的幂。
当且仅当 n & (n-1) == 0 成立时，n为2的幂。题目 LeetCode231. 2 的幂 使用到该技巧。
同理，如果要判断n的二进制是否均由1构成，也可以用类似的方法判断。
当且仅当n & (n+1) == 0 成立时，n的二进制均由1构成。
"""
n = 16
if n & (n-1) == 0:
    print("n是2的幂")

n = 15
if n & (n+1) == 0:
    print("n的二进制数均由1构成")